package main

// $ go mod init github.com/zhangxi/rpc_hello
// $ ==> go mod init rpc_hello
// $ go mod tidy  #==> 下载项目中引入的第三方包,

import (
	"fmt"
	"net"
	"net/rpc"
)

// 1.定义一个远程调用的方法,
type Hello struct{}

// (a). 方法只能有两个可序列化的参数, 其中第二个参数是指针类型,
//
//	req 表示客户端传过来的数据, resp表示给客户端返回的数据,
//
// (b). 方法要返回一个 error 类型, 并且必须是 Public 的方法,
// (c). req  resp 的类型不能是 channel  complex  func, 均不能进行序列化,
func (this Hello) SayHello(req string, resp *string) error {
	fmt.Println("req:", req)
	*resp = "ninhao " + req
	return nil
}

func main() {
	// 1.注册 rpc 服务,
	err1 := rpc.RegisterName("hello_service", new(Hello))
	if err1 != nil {
		fmt.Println("rpc.RegisterName() err:", err1)
		return
	}
	// 2.监听端口,
	listener, err2 := net.Listen("tcp", "0.0.0.0:8080")
	if err2 != nil {
		fmt.Println("net.Listen() err:", err2)
		return
	}
	// 3.应用退出时候关闭监听端口,
	defer listener.Close()
	// 4.建立连接,
	for {
		fmt.Println("开始建立连接...")
		conn, err3 := listener.Accept()
		if err3 != nil {
			fmt.Println("listener.Accept() err:", err3)
			continue
		}
		// 5.绑定服务,
		go func() {
			rpc.ServeConn(conn)
		}()
	}

}
